package xcmg.device.service.report;


import com.github.pagehelper.PageInfo;
import xcmg.device.service.vo.company.CompanyInfoVO;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.ReportMapper;
import xcmg.device.dao.mapper.report.LackInboundMapper;
import xcmg.device.dao.mapper.report.LackRecordMapper;
import xcmg.device.infra.ExportUtil;
import xcmg.device.service.vo.basic.MaterialsStorageVO;
import xcmg.device.service.vo.report.MissingVO;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class LackService {

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private LackRecordMapper lackRecordMapper;

    @Autowired
    private LackInboundMapper lackInboundMapper;
    @Autowired
    private ReportMapper reportMapper;

    public void saveLack() {
//        LogHelper.monitor("========更新缺货到件提示开始========");
//        CompanyInfoDO record = new CompanyInfoDO();
//        record.setIsSap(1);
//        List<CompanyInfoDO> companyInfoDOList = companyInfoMapper.list(record);
//        if(ListUtil.isNullOrEmpty(companyInfoDOList)){
//            return;
//        }
//        for(CompanyInfoDO companyInfoDO : companyInfoDOList){
//            LogHelper.monitor("========当前企业："+companyInfoDO.getCompanyName()+"========");
//            this.saveLack(companyInfoDO.getOrgId());
//        }
//        LogHelper.monitor("========更新缺货到件提示结束========");
    }

    private void saveLack(String orgId) {
        MaterialsStorageVO condition = new MaterialsStorageVO();
        condition.setOrgId(orgId);
        condition.setIsLack(1);
        Integer count = priMaterialsMapper.materialStorageCount(condition);
        List<MaterialsStorageVO> dataList = new ArrayList<>();
        int times = count/1000+1;
        for(int i=0; i<times; i++){
            PageHelperPlus.startPage(i + 1, 1000);
            dataList.addAll(priMaterialsMapper.materialStorage(condition));
        }

        List<MaterialsStorageVO> lackList = new ArrayList<>();
        count = lackRecordMapper.listCount(orgId);
        times = count/1000+1;
        for(int i=0; i<times; i++){
            PageHelperPlus.startPage(i + 1, 1000);
            lackList.addAll(lackRecordMapper.list(orgId));
        }

        this.invoke(dataList, lackList, orgId);
    }

    private void invoke(List<MaterialsStorageVO> dataList, List<MaterialsStorageVO> lackList, String orgId){
        Map<String, MaterialsStorageVO> dataMap = new HashMap<>();
        Map<String, MaterialsStorageVO> lackMap = new HashMap<>();
        for(MaterialsStorageVO entity : dataList){
            dataMap.put(entity.getOrgId()+"_"+entity.getBillNo()+"_"+entity.getMaterialsNo(), entity);
        }
        for(MaterialsStorageVO entity : lackList){
            lackMap.put(entity.getOrgId()+"_"+entity.getBillNo()+"_"+entity.getMaterialsNo(), entity);
        }
        List<MaterialsStorageVO> insertList = new ArrayList<>();
        List<MaterialsStorageVO> inboundList = new ArrayList<>();
        List<Long> idsList = new ArrayList<>();
        Iterator<Map.Entry<String, MaterialsStorageVO>> entries = dataMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, MaterialsStorageVO> entry = entries.next();
            if(!lackMap.containsKey(entry.getKey())){
                insertList.add(entry.getValue());
            }
        }

        entries = lackMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, MaterialsStorageVO> entry = entries.next();
            if(!dataMap.containsKey(entry.getKey())){
                inboundList.add(entry.getValue());
                idsList.add(entry.getValue().getId());
            }
        }

        LogHelper.monitor("========缺货记录数："+insertList.size()+"，缺货到件记录数："+inboundList.size()+"========");

        if(!ListUtil.isNullOrEmpty(insertList)){
            int times = insertList.size()/1000;
            int ot = insertList.size()%1000;
            for(int i=0; i<times; i++){
                lackRecordMapper.batchInsert(insertList.subList(i*1000, (i+1)*1000));
            }
            if(ot > 0){
                lackRecordMapper.batchInsert(insertList.subList(times*1000, insertList.size()));
            }
        }
        if(!ListUtil.isNullOrEmpty(idsList)){
            int times = idsList.size()/800;
            int ot = idsList.size()%800;
            for(int i=0; i<times; i++){
                lackRecordMapper.batchRemove(idsList.subList(i*800, (i+1)*800));
            }
            if(ot > 0){
                lackRecordMapper.batchRemove(idsList.subList(times*800, idsList.size()));
            }
        }
        if(!ListUtil.isNullOrEmpty(inboundList)){
            int times = inboundList.size()/1000;
            int ot = inboundList.size()%1000;
            for(int i=0; i<times; i++){
                lackInboundMapper.batchInsert(inboundList.subList(i*1000, (i+1)*1000));
            }
            if(ot > 0){
                lackInboundMapper.batchInsert(inboundList.subList(times*1000, inboundList.size()));
            }
        }

        List<Long> ids = lackInboundMapper.findDeleteIds(orgId);
        if(!ListUtil.isNullOrEmpty(ids)){
            lackInboundMapper.batchRemove(ids);
        }
    }

    public PageCommonVO<MaterialsStorageVO> materialStorage(SearchCommonVO<MaterialsStorageVO> condition) {
        PageCommonVO<MaterialsStorageVO> result = new PageCommonVO<>();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        PageHelperPlus.orderBy("MATERIALS_NO,CREATE_TIME asc");
        List<MaterialsStorageVO> storageVOList = lackInboundMapper.list(condition.getFilters());
        result.setPageInfo(new PageInfo(storageVOList));
        result.setPageInfoList(storageVOList);
        return result;
    }

    public Integer getLackInboundNum(String orgId){
        MaterialsStorageVO condition = new MaterialsStorageVO();
        condition.setOrgId(orgId);
        return lackInboundMapper.listCount(condition);
    }

    public void materialStorageExportAll(MaterialsStorageVO condition) throws Exception{
        Integer count = lackInboundMapper.listCount(condition);
        List<MaterialsStorageVO> dataList = new ArrayList<>();
        int times = count/1000+1;
        for(int i=0; i<times; i++){
            PageHelperPlus.startPage(i + 1, 1000);
            dataList.addAll(lackInboundMapper.list(condition));
        }
        materialStorageExport(dataList);
    }

    private void materialStorageExport(List<MaterialsStorageVO> voList)throws Exception{
        String title = "缺货到件提示报表数据导出";
        String[] rowsName = new String[]{"序号","客户编号","客户名称","单据编号","单据类型","采购级别","备注","出库类型",
                "创建时间","零件编号","零件名称","零件分类","单价","需求数量","未分发数量","总库存", "计划外仓库库存", "计划内仓库库存", "交付时间"};
        List<Object[]>  dataList = new ArrayList<Object[]>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < voList.size(); i++) {
            MaterialsStorageVO e = voList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i+1;
            objs[1] =e.getDealerCode();
            objs[2] =e.getDealerName();
            objs[3] = e.getBillNo();
            objs[4] = e.getBillType();
            objs[5] = e.getPurchaseLevelName();
            objs[6] = e.getRemark();
            objs[7] = e.getOutType();
            objs[8]= sdf.format(e.getCreateTime());
            objs[9]=e.getMaterialsNo();
            objs[10]=e.getMaterialsDes();
            objs[11]=e.getMaterialsType();
            objs[12]=e.getPrice();
            objs[13]=e.getNeedQty();
            objs[14]=e.getNotInformQty();
            objs[15]=e.getAllInventory();
            objs[16]=e.getOutInventory();
            objs[17]=e.getInInventory();
            objs[18]=e.getDeliveryDate()==null?"":sdf.format(e.getDeliveryDate());
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }


    public void missingAnalysisScheduled() {
        LogHelper.monitor("========更新备件订单缺项分析提示开始========");
        CompanyInfoVO record = new CompanyInfoVO();
        record.setIsSap(1);
        List<CompanyInfoDO> companyInfoDOList = companyInfoMapper.list(record);
        if (ListUtil.isNullOrEmpty(companyInfoDOList)) {
            return;
        }
        for (CompanyInfoDO companyInfoDO : companyInfoDOList) {
            LogHelper.monitor("========当前企业：" + companyInfoDO.getCompanyName() + "========");
            this.missingAnalysisScheduledExecute(companyInfoDO.getOrgId());
        }
        LogHelper.monitor("========更新备件订单缺项分析提示结束========");
    }

    private void missingAnalysisScheduledExecute(String orgId) {
        reportMapper.deleteMissingAnalysis(orgId);
        MissingVO queryParam = new MissingVO();
        queryParam.setOrgId(orgId);
        //实时缺项分析报表-调度员
        List<MissingVO> resultList = new ArrayList<>();
        List<MissingVO> dispatcherDoList = reportMapper.missingDispatcher(queryParam);
        dispatcherDoList.forEach(x->{
            x.setType(0);
            x.setOrgId(orgId);
        });
        resultList.addAll(dispatcherDoList);
        //实时缺项分析报表-代理商
        List<MissingVO> agentDoList = reportMapper.missingAgent(queryParam);
        agentDoList.forEach(x->{
            x.setType(1);
            x.setOrgId(orgId);
        });
        resultList.addAll(agentDoList);
        //实时缺项分析报表-订单类型
        List<MissingVO> orderTypeDoList = reportMapper.missingOrderType(queryParam);
        orderTypeDoList.forEach(x->{
            x.setType(2);
            x.setOrgId(orgId);
        });
        resultList.addAll(orderTypeDoList);
        //实时缺项分析报表-零件归属
        List<MissingVO> materialOwnershipDoList = reportMapper.missingMaterialOwnership(queryParam);
        materialOwnershipDoList.forEach(x->{
            x.setType(3);
            x.setOrgId(orgId);
        });
        resultList.addAll(materialOwnershipDoList);
        //插入缺项分析表
        List<List<MissingVO>> splitList = splitList(resultList, 500);
        for (List<MissingVO> list: splitList) {
            reportMapper.batchInsertMissingAnalysis(list);
        }
    }

    /**
     * 按指定大小，分隔集合，将集合按规定个数分为n个部分
     *
     * @param list 参数
     * @param len  指定长度
     */
    private List<List<MissingVO>> splitList(List<MissingVO> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<MissingVO>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<MissingVO> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

}
